package com.zksk.mbg;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.TemplateType;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;
import com.zksk.common.core.web.domain.BaseEntity;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

/**
 * <p>
 * 快速生成
 * </p>
 *
 * @author ZSAndroid
 * @create 2021-10-1-10:08
 */

@Slf4j
public class CodeGenerator {

    static final String[] tables = new String[]{
            "platform_fact_member_invoice_record",//(用户开票记录表)
//            "platform_fact_policy_info", //（政策资讯信息表）
//            "platform_fact_violate",     // （违规资讯信息表）
//            "platform_fact_sanctions",   // （奖惩信息表）
//            "platform_fact_manual",      //（操作手册信息表）
//            "platform_fact_policy_info",//政策资讯信息表
//            "platform_fact_carousel",
//            "platform_fact_member",//门户企业用户表
//            "platform_fact_member_score", // 用户业绩信息表
//            "platform_fact_member_credential",// 用户资质证书表
//            "platform_fact_credential_level",// 资质证书等级表
//            "platform_fact_member_operator",//经办人信息表
//            "platform_fact_member_manage",//用户经营信息表
//            "platform_fact_member_invoice",// 用户发票信息表
//            "platform_fact_member_invoice_record",// 用户开票记录表
//            "platform_fact_sale",//用户营销产品表
//            "platform_fact_sale_record",//营销记录表
//            "platform_fact_section",//标段表,
//            "platform_fact_biding",//招标实时数据表
//            "platform_fact_win",//中标信息表
//            "platform_fact_winning",//中标实时数据表
//            "platform_fact_orders",//订单表
//            "platform_fact_orders_agreement",//订单签订协议表
//            "platform_fact_orders_guarantee",//订单保函信息表
//            "platform_log_orders_op",//订单操作日志表
//            "platform_fact_orders_question",//订单问题表
//            "platform_fact_comment",//用户评价表
//            "platform_fact_orders_snapshot",//订单快照表
//            "platform_fact_orders_cancel",//退订订单信息表
//            "platform_fact_cancel_process",//推定审核记录表
//            "platform_agreement",// 协议表
//            "platform_customer",// 客户表
//            "platform_customer_prod_req",// 客户对产品要求（描述）（支付方式、CA厂家等）
//            "platform_economic_company", // 经纪公司
//            "platform_field_select",// 机构对于标段信息得展示字段、
//            "platform_member",// 用户（企业）
//            "platform_org",// 机构
//            "platform_org_product",// 机构推出的产品服务
//            "platform_product_enum",// 产品枚举
//            "platform_product_release",// 发行的产品（实际的业务 客户与机构的关系）
//            "platform_rate",// 费率
//             "platform_ca_company"
//            "platform_r_agreement_customer_req",// 关系：
//            "platform_r_prod_field",//
//            "platform_r_rate_customer_req",//
//            "platform_r_rate_org_prod"//
//            "platform_r_org_prod_field"
//            "platform_r_agreement_customer_req",
//            "platform_r_agreement_org_prod"
//            "platform_r_agreement_customer_req",//客户（平台）提供给用户得保函模板
//            "platform_r_rate_customer_req"//客户（平台）对产品的要求与费率关系表
//            "sys_dict_area"
    };

    /**
     * 执行 run
     */
    public static void main(String[] args) {
        //用来获取Mybatis-Plus.properties文件的配置信息
        ResourceBundle rb = ResourceBundle.getBundle("genreator");
        //项目根目录  不可修改
        String projectPath = System.getProperty("user.dir")+"/platform-mbg/";
        String moudulesName = "admin"; // 模块 根据项目框架选择生成代码的目录 admin 后台/platform 门户
        log.info("项目根路径"+projectPath);
        /**
         * 数据源配置
         */
        DataSourceConfig.Builder DATA_SOURCE_CONFIG = new DataSourceConfig
                .Builder(rb.getString("jdbc.url"), rb.getString("jdbc.username"), rb.getString("jdbc.password"))
                .dbQuery(new MySqlQuery()) //数据库查询
                .schema(rb.getString("jdbc.schema")) //数据库schema(部分数据库适用)
                .typeConvert(new MySqlTypeConvert()) //数据库类型转换器
                .keyWordsHandler(new MySqlKeyWordsHandler()); //数据库关键字处理器

//        "C://Users//ZSAndroid//Desktop//mybatisDemo//src//main//java"
        FastAutoGenerator.create(DATA_SOURCE_CONFIG)
                // 全局配置
                .globalConfig((scanner, builder) -> builder
                        .fileOverride() //覆盖已生成文件，默认值:false
                        .outputDir(projectPath + "/src/main/java") //指定输出目录，默认值: windows:D://
                        .author(rb.getString("author"))//作者名，baomidou 默认值:作者
                        .dateType(DateType.TIME_PACK)//时间策略，DateType.ONLY_DATE 默认值: DateType.TIME_PACK
                        .commentDate("yyyy-MM-dd")//注释日期，默认值: yyyy-MM-dd
                        //.disableOpenDir()// 禁止打开输出目录，默认值:true
                        //.enableKotlin() //开启 kotlin 模式，默认值:false
                        .enableSwagger() //开启 swagger 模式，默认值:false
                        .build()//加入构建队列
                )
                // 包配置
                .packageConfig((scanner, builder) -> {
//                    Collections.singletonMap(OutputFile.mapperXml, projectPath + "src/main/resources/mapper/" + moudulesName);
                    Map<OutputFile, String> outputFileStringMap = new HashMap<>();
                    outputFileStringMap.put(OutputFile.mapperXml, projectPath + "src/main/resources/mapper/" + moudulesName);
//                    outputFileStringMap.put(OutputFile.serviceImpl, codeSrcPath + "/src/main/java/com/zksk/" + moudulesName + "/service/impl/");
//                    outputFileStringMap.put(OutputFile.service, codeSrcPath + "/src/main/java/com/zksk/" + moudulesName + "/service/");

                    builder
//                  .parent(scanner.apply("请输入上级包名(例：com.zksk.gen.bussiness)"))//父包名 如:com.zksk.gen.bussiness
                    .parent("com.zksk.mbg")//父包名 如:com.zksk.mbg
                    .moduleName(moudulesName)//父包模块名，默认值:无
                    .entity("domain")//Entity 包名，默认值:entity
                    .service("service")//Service 包名，默认值:service
                    .serviceImpl("service.impl")//Service Impl 包名，默认值:service.impl
                    .mapper("mapper")//Mapper 包名，默认值:mapper
                    .xml("mapper.xml")//Mapper XML 包名，默认值:mapper.xml
                    .controller("controller")//Controller 包名，默认值:controller
                    //.other("other")//自定义文件包名,	输出自定义文件时所用到的包名
                    .pathInfo(outputFileStringMap) //路径配置信息，Collections.singletonMap(OutputFile.mapperXml, "D://")
                    .build();//加入构建队列
                })

                //模板配置
                .templateConfig((scanner, builder) -> builder
                        //.disable()//禁用所有模板
//                        .entityKt("/templates/entity.java")// 设置实体模板路径(kotlin)，/templates/entity.java
                        .disable(TemplateType.CONTROLLER, TemplateType.SERVICE, TemplateType.SERVICEIMPL)//禁用模板 TemplateType.ENTITY.disable(TemplateType.CONTROLLER, TemplateType.SERVICE, TemplateType.SERVICEIMPL)//禁用模板 TemplateType.ENTITY
                        .entity("/templates/entity.java") //设置实体模板路径(JAVA)，/templates/entity.java
//                        .service("/templates/service.java")//设置 service 模板路径，/templates/service.java
//                        .serviceImpl("/templates/serviceImpl.java")//设置 serviceImpl 模板路径，/templates/serviceImpl.java
                        .mapper("/templates/mapper.java")//设置 mapper 模板路径，/templates/mapper.java
                        .mapperXml("/templates/mapper.xml")//设置 mapperXml 模板路径，/templates/mapper.xml
//                        .controller("/templates/controller.java")//设置 controller 模板路径，/templates/controller.java
                        .build()//加入构建队列
                )
                // 策略配置
                /**
                 * schema：在数据库中表示的是数据库对象集合，它包含了各种对像，比如：表，视图，存储过程，索引等等。
                 * 一般情况下一个用户对应一个集合，所以为了区分不同的集合就需要给不同的集合起名字。
                 * 用户的schema名就相当于用户名，并作为该用户缺省schema。所以说schema集合看上去像用户名。
                 * 例如当我们访问一个数据表时，如果该表没有指明属于哪个schema，系统就会自动的加上缺省的schema。
                 */
                .strategyConfig(builder -> builder
                        /** 基本参数配置 */
                        .enableCapitalMode()//开启大写命名，默认值:false
                        .enableSkipView()//开启跳过视图，默认值:false
                        .disableSqlFilter()//禁用 sql 过滤，默认值:true，语法不能支持使用 sql 过滤表的话，可以考虑关闭此开关
//                        .likeTable(new LikeTable("ca_"))//模糊表匹配(sql 过滤)	likeTable 与 notLikeTable 只能配置一项
                        /** 设置需要生成的表名 */
                        .addInclude(tables)// 增加表匹配(内存过滤)，include 与 exclude 只能配置一项
                        /** 前缀配置*/
                        .addTablePrefix("platform_fact_")//增加过滤表前缀
//                        .addTablePrefix("platform_")//增加过滤表前缀
                        //.addFieldSuffix("_")//增加过滤表后缀
                        //.addFieldPrefix("ul_")//增加过滤字段前缀  本人不建议使用，去掉后缀，会导致驼峰命名实体类的变量名不带前缀，去掉后,错误：Username，正确:ulUsername
                        //.addFieldSuffix("_")//增加过滤字段后缀
                        /** 实体策略配置 */
                        .entityBuilder()//实体策略配置
                        .superClass(BaseEntity.class)
                        // 父类字段
                        .addSuperEntityColumns("search_value","create_time", "create_by", "update_time", "update_by", "status", "remark")
                        .disableSerialVersionUID()//禁用生成 serialVersionUID，默认值:true
                        .enableLombok()//开启 lombok 模型，默认值:false
                        .enableChainModel()//开启链式模型，默认值:false
                        .enableRemoveIsPrefix()//开启 Boolean 类型字段移除 is 前缀，默认值:false
                        .enableTableFieldAnnotation()//开启生成实体时生成字段注解，默认值:false
                        .enableActiveRecord()//开启 ActiveRecord 模型，默认值:false
                        .naming(NamingStrategy.underline_to_camel)//数据库表映射到实体的命名策略，默认下划线转驼峰命名:NamingStrategy.underline_to_camel
                        .columnNaming(NamingStrategy.underline_to_camel)//数据库表字段映射到实体属性的命名策略，默认为 null，未指定按照 naming 执行
                        .idType(IdType.ASSIGN_ID)//全局主键类型 设置mybatis-plus生成实体id为雪花算法
//                        .formatFileName("%sBean")//格式化文件名称，生成实体的后缀，建议这样使用，生成后：UserLoginBean
//                        .superClass(BaseEntity.class)//设置父类
                        .enableColumnConstant()//开启生成字段常量，默认值:false
                        //.addIgnoreColumns("age")//添加忽略字段
                        //.nameConvert(INameConvert)//名称转换实现
                        //.versionColumnName("version")//乐观锁字段名(数据库)
                        //.versionPropertyName("version")//乐观锁属性名(实体)
                        .logicDeleteColumnName("del_flag")//逻辑删除字段名(数据库)
                        .logicDeletePropertyName("delFlag")//逻辑删除属性名(实体)
                        .addTableFills(new Column("create_time", FieldFill.INSERT)) // 表字段填充
                        .addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE)) // 表字段填充
                        .addTableFills(new Column("del_flag", FieldFill.INSERT)) // 表字段填充
                        //.enableSchema()//启用 schema，默认值:false，多 schema 场景的时候打开
                        //.addExclude("t_simple")//增加表排除匹配(内存过滤)，include 与 exclude 只能配置一项
                        //.notLikeTable(new LikeTable("USER"))//模糊表排除(sql 过滤)	likeTable 与 notLikeTable 只能配置一项
                        /** controller 策略配置 */
                        .controllerBuilder()//controller 策略配置
                        .enableHyphenStyle()//开启驼峰转连字符，默认值:false
                        .enableRestStyle()//开启生成@RestController 控制器，默认值:false
                        .formatFileName("%sController")//格式化文件名称——controller包下自动生成的类后缀，例如UserLoginController

                        /** Service 策略配置 */
                        .serviceBuilder()//service 策略配置
                        .formatServiceFileName("%sService")//转换 service 接口文件名称，例如：UserLoginService
                        .formatServiceImplFileName("%sServiceImpl")//转换 service 实现类文件名称，例如：UserLoginServiceImpl

                        /** mapper 策略配置 */
                        .mapperBuilder()//mapper 策略配置
                        .superClass(BaseMapper.class)//设置父类，BaseMapper是com.baomidou.mybatisplus.core.mapper中的
                        .enableMapperAnnotation()//开启 @Mapper 注解，默认值:false
                        .enableBaseResultMap()//启用 BaseResultMap 生成，默认值:false
                        .enableBaseColumnList()//启用 BaseColumnList，默认值:false
                        .formatMapperFileName("%sMapper")//转换 mapper 接口文件名称后缀，mapper目录下的，例如：UserLoginMapper（有@Mapper）
                        .formatXmlFileName("%sMapper")//转换 xml 文件名称后缀，例如：UserLoginMapper.xml，Mybatis的xml映射文件
                        .build()//加入构建队列
                ) // 注入配置
//                .injectionConfig((scanner, builder) -> {
//                    // 自定义vo，ro，qo等数据模型
//                    Map<String, String> customFile = new HashMap<>();
//                    customFile.put("VO.java", "templates/entity.java.vm");
//                    customFile.put("RO.java", "templates/ro.java.vm");
//                    customFile.put("QO.java", "templates/qo.java.vm");
//                    customFile.put("URO.java", "templates/uro.java.vm");
//                    // 自定义MapStruct
//                    customFile.put("Converter.java", "templates/converter/converter.java.vm");
//
//                    // 自定义配置对象
//                    Map<String, Object> customMap = new HashMap<>();
//                    customMap.put("vo", "VO");
//                    customMap.put("ro", "RO");
//                    customMap.put("qo", "QO");
//                    customMap.put("uro", "URO");
//                    builder.customFile(customFile).customMap(customMap); // 自定义模板
//                    // 自定义map
//                })
                /**
                 * 模板引擎
                 */
                //Velocity
                .templateEngine(new VelocityTemplateEngine())
                //Beetl
                //.templateEngine(new BeetlTemplateEngine())
                //Freemarker
//                .templateEngine(new FreemarkerTemplateEngine())
                /**
                 * 开始自动生成代码,执行队列构建操作
                 */
                .execute();
    }
}
